/**
 * 通用工具函数库
 * 提供全局共享的工具函数，减少代码冗余
 */

const { logger } = require('./logger')

/**
 * 格式化时间
 * @param {Date} date 日期对象
 * @param {boolean} showMS 是否显示毫秒
 * @returns {string} 格式化后的时间字符串
 */
function formatTime(date, showMS = false) {
  if (!date || !(date instanceof Date)) {
    date = new Date()
  }

  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()
  const hour = date.getHours()
  const minute = date.getMinutes()
  const second = date.getSeconds()

  // 补零函数
  const formatNumber = n => {
    n = n.toString()
    return n[1] ? n : `0${n}`
  }

  if (showMS) {
    const millisecond = date.getMilliseconds()
    return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}:${millisecond}`
  }

  return `${[year, month, day].map(formatNumber).join('/')} ${[hour, minute, second].map(formatNumber).join(':')}`
}

/**
 * 格式化日期
 * @param {Date} date 日期对象
 * @returns {string} 格式化后的日期字符串 YYYY-MM-DD
 */
function formatDate(date) {
  if (!date || !(date instanceof Date)) {
    date = new Date()
  }

  const year = date.getFullYear()
  const month = date.getMonth() + 1
  const day = date.getDate()

  // 补零函数
  const formatNumber = n => {
    n = n.toString()
    return n[1] ? n : `0${n}`
  }

  return `${[year, month, day].map(formatNumber).join('-')}`
}

/**
 * 生成随机字符串ID
 * @param {number} length ID长度
 * @returns {string} 随机字符串ID
 */
function generateRandomId(length = 8) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  let result = ''

  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }

  return result
}

/**
 * 防抖函数
 * @param {Function} func 需要防抖的函数
 * @param {number} wait 延迟执行的毫秒数
 * @param {boolean} immediate 是否立即执行
 * @returns {Function} 返回新的防抖函数
 */
function debounce(func, wait, immediate) {
  let timeout;
  
  return function(...args) {
    const context = this;
    
    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };
    
    const callNow = immediate && !timeout;
    
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
    
    if (callNow) func.apply(context, args);
  };
}

/**
 * 节流函数
 * @param {Function} func 需要节流的函数
 * @param {number} wait 延迟执行的毫秒数
 * @param {Object} options 配置选项
 * @returns {Function} 返回新的节流函数
 */
function throttle(func, wait, options) {
  let timeout = null;
  let previous = 0;
  
  if (!options) options = {};
  
  return function(...args) {
    const context = this;
    const now = Date.now();
    
    if (!previous && options.leading === false) previous = now;
    
    const remaining = wait - (now - previous);
    
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      
      previous = now;
      func.apply(context, args);
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(function() {
        previous = options.leading === false ? 0 : Date.now();
        timeout = null;
        func.apply(context, args);
      }, remaining);
    }
  };
}

/**
 * 界面交互工具函数
 */
const ui = {
  /**
   * 显示提示信息
   * @param {string} message - 提示内容
   * @param {string} icon - 图标类型，可选值：'success', 'error', 'loading', 'none'
   * @param {number} duration - 显示时长(ms)
   */
  showToast: function (message, icon = 'none', duration = 1500) {
    wx.showToast({
      title: message,
      icon: icon,
      duration: duration,
    })
  },

  /**
   * 显示确认对话框
   * @param {string} title - 标题
   * @param {string} content - 内容
   * @param {Function} onConfirm - 确认回调
   * @param {Function} onCancel - 取消回调
   */
  showConfirm: function (title, content, onConfirm, onCancel) {
    wx.showModal({
      title: title,
      content: content,
      success: res => {
        if (res.confirm && typeof onConfirm === 'function') {
          onConfirm()
        } else if (res.cancel && typeof onCancel === 'function') {
          onCancel()
        }
      },
    })
  },
}

/**
 * 创建批量更新管理器
 * @param {Object} context - 页面或组件的实例对象(this)
 * @param {Object} options - 配置选项
 * @returns {Object} 批量更新管理器对象
 */
function createBatchUpdater(context, options = {}) {
  if (!context || typeof context.setData !== 'function') {
    console.error('createBatchUpdater: 无效的context参数');
    return null;
  }

  // 默认配置
  const config = {
    waitTime: options.waitTime || 50, // 批量更新等待时间，默认50ms
    immediate: options.immediate || false, // 是否立即更新首次调用
    enableLog: options.enableLog || false, // 是否启用日志
    logLevel: options.logLevel || 'warn', // 日志级别
  };

  // 待更新数据
  let pendingData = {};
  // 是否正在等待更新
  let isWaiting = false;
  // 更新计数器
  let updateCount = 0;
  
  // 使用防抖函数创建更新函数
  const debouncedUpdate = debounce(function() {
    if (Object.keys(pendingData).length === 0) {
      return;
    }
    
    // 记录此次更新的数据数量
    const dataCount = Object.keys(pendingData).length;
    updateCount++;
    
    if (config.enableLog) {
      console.log(`BatchUpdater: 执行批量更新 #${updateCount}, 数据项: ${dataCount}`);
    }
    
    // 执行实际的setData调用
    context.setData(pendingData, function() {
      if (config.enableLog) {
        console.log(`BatchUpdater: 批量更新 #${updateCount} 完成`);
      }
    });
    
    // 清空待更新数据
    pendingData = {};
    isWaiting = false;
  }, config.waitTime, config.immediate);
  
  // 返回批量更新管理器对象
  return {
    update: function(data, callback) { // 批量更新
      // 合并数据到待更新队列
      Object.assign(pendingData, data);
      isWaiting = true;
      
      // 触发防抖更新
      debouncedUpdate();
      
      // 如果有回调，立即执行
      if (typeof callback === 'function') {
        callback();
      }
    },
    forceUpdate: function(data, callback) { // 强制立即更新
      // 合并之前待更新的数据
      if (Object.keys(pendingData).length > 0) {
        Object.assign(data, pendingData);
        pendingData = {};
      }
      
      updateCount++;
      isWaiting = false;
      
      if (config.enableLog) {
        console.log(`BatchUpdater: 强制更新 #${updateCount}, 数据项: ${Object.keys(data).length}`);
      }
      
      // 直接调用setData
      context.setData(data, callback);
    },
    flush: function(callback) { // 刷新所有待更新数据
      if (Object.keys(pendingData).length > 0) {
        this.forceUpdate(pendingData, callback);
      } else if (typeof callback === 'function') {
        callback();
      }
    },
    isPending: function() { // 是否有待更新数据
      return isWaiting;
    },
    getPendingCount: function() { // 获取待更新数据项数量
      return Object.keys(pendingData).length;
    },
    getUpdateCount: function() { // 获取已执行的更新次数
      return updateCount;
    }
  };
}

/**
 * 格式化文件大小
 * @param {number} bytes - 字节数
 * @returns {string} 格式化后的大小
 */
function formatFileSize(bytes) {
  if (bytes === 0) return '0 B'

  const units = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(1024))
  return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + units[i]
}

/**
 * 统一导出工具函数
 */
module.exports = {
  ui,
  formatTime,
  formatDate,
  generateRandomId,
  debounce,
  throttle,
  createBatchUpdater,
  formatFileSize
}
